package ice.controller;

import ice.Main;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.input.MouseEvent;
import javafx.stage.FileChooser;

import java.io.*;
import java.net.URL;
import java.util.Arrays;
import java.util.ResourceBundle;

public class 高级 implements Initializable {
    @FXML
    private TextField turl;
    @FXML
    private TextArea tsqlcmd;
    @FXML
    private CheckBox cdb类型;
    @FXML
    private ChoiceBox tdb类型;
    @FXML
    private CheckBox c参数;
    @FXML
    private TextField t参数;
    @FXML
    private CheckBox c前缀;
    @FXML
    private TextField t前缀;
    @FXML
    private CheckBox c后缀;
    @FXML
    private TextField t后缀;
    @FXML
    private CheckBox cos;
    @FXML
    private TextField tos;
    @FXML
    private CheckBox c跳参数;
    @FXML
    private TextField t跳参数;
    @FXML
    private CheckBox c逻辑;
    @FXML
    private ListView<String> t脚本;
    @FXML
    private CheckBox c所有优化;
    @FXML
    private CheckBox c预测结果;
    @FXML
    private CheckBox c持续连接;
    @FXML
    private CheckBox c只长度;
    @FXML
    private CheckBox c线程;
    @FXML
    private ChoiceBox t线程;
    @FXML
    private CheckBox c字符串;
    @FXML
    private CheckBox c正则;
    @FXML
    private CheckBox c代码;
    @FXML
    private CheckBox c等级;
    @FXML
    private CheckBox c风险;
    @FXML
    private TextField t字符串;
    @FXML
    private TextField t正则;
    @FXML
    private TextField t代码;
    @FXML
    private ChoiceBox t等级;
    @FXML
    private ChoiceBox t风险;
    @FXML
    private CheckBox c技术;
    @FXML
    private CheckBox cu数;
    @FXML
    private CheckBox cu字符;
    @FXML
    private CheckBox c延迟;
    @FXML
    private ChoiceBox t技术;
    @FXML
    private TextField tu数;
    @FXML
    private TextField tu字符;
    @FXML
    private TextField t延迟;
    @FXML
    private CheckBox c指纹;
    @FXML
    private CheckBox c版本;
    @FXML
    private CheckBox chex;
    @FXML
    private CheckBox c无交互;
    @FXML
    private CheckBox c详细度;
    @FXML
    private ChoiceBox t详细度;
    @FXML
    private CheckBox cpost;
    @FXML
    private CheckBox ccookie;
    @FXML
    private TextField tpost;
    @FXML
    private TextField tcookie;
    @FXML
    private CheckBox c当前用户;
    @FXML
    private CheckBox c当前库;
    @FXML
    private CheckBox c是否dba;
    @FXML
    private CheckBox c所有用户;
    @FXML
    private CheckBox c密码;
    @FXML
    private CheckBox c权限;
    @FXML
    private CheckBox c角色;
    @FXML
    private CheckBox c数据库;
    @FXML
    private CheckBox c表;
    @FXML
    private CheckBox c字段;
    @FXML
    private CheckBox c架构;
    @FXML
    private CheckBox c计数;
    @FXML
    private CheckBox cdump;
    @FXML
    private CheckBox c脱裤;
    @FXML
    private CheckBox c搜索;
    @FXML
    private CheckBox c排除系统库;
    @FXML
    private CheckBox c第一字符;
    @FXML
    private CheckBox c第二字符;
    @FXML
    private TextField t第一字符;
    @FXML
    private TextField t第二字符;
    @FXML
    private CheckBox c始;
    @FXML
    private CheckBox c末;
    @FXML
    private TextField t始;
    @FXML
    private TextField t末;
    @FXML
    private CheckBox c指定db;
    @FXML
    private CheckBox c指定表;
    @FXML
    private CheckBox c指定列;
    @FXML
    private TextField t指定db;
    @FXML
    private TextField t指定表;
    @FXML
    private TextField t指定列;
    @FXML
    private CheckBox csql;
    @FXML
    private TextField tsql;
    @FXML
    private CheckBox c代理;
    @FXML
    private CheckBox c身份验证;
    @FXML
    private TextField t代理;
    @FXML
    private TextField tname;
    @FXML
    private TextField t密码;
    @FXML
    private Button 按钮构造;
    @FXML
    private Button 按钮开始;

    @FXML
    private Button b请求文件;

    @FXML
    private TextField t请求文件;

    @FXML
    private CheckBox c请求文件;

    @FXML
    private CheckBox c读文件;

    @FXML
    private TextField t读文件;

    @FXML
    private CheckBox cShell;

    @FXML
    private CheckBox c编辑文件;

    @FXML
    private TextField t编辑文件;

    @FXML
    private TextField t写入文件;

    @FXML
    private CheckBox c写入文件;

    private String data="";
    private static File sqlcmd = null;

    /*
     *  作者：icefield
     *  说明：判断操作系统环境，生成相应的脚本文件
     */
    static{
        if (Main.OSname.equals("Windows")){
            sqlcmd = new File(System.getProperty("user.home")+"/sqlcmd.bat");
        } else if(Main.OSname.equals("Linux")){
            sqlcmd = new File(System.getProperty("user.home")+"/sqlcmd.sh");
        }
    }

    /*
     *  作者：icefield
     *  说明：界面初始化
     */
    @Override
    public void initialize(URL location, ResourceBundle resources) {
        tdb类型.getItems().addAll("access","db2","firebird","maxdb","mssqlserver","mysql","oracle","postgresql","sqlite","sybase");
        tdb类型.getSelectionModel().selectFirst();

        t线程.getItems().addAll(1,2,3,4,5,6,7,8,9,10);
        t线程.getSelectionModel().selectFirst();

        t等级.getItems().addAll(1,2,3,4,5);
        t等级.getSelectionModel().selectFirst();

        t风险.getItems().addAll(1,2,3);
        t风险.getSelectionModel().selectFirst();

        t技术.getItems().addAll("B","E","U","S","t");
        t技术.getSelectionModel().selectFirst();

        t详细度.getItems().addAll(1,2,3,4,5,6);
        t详细度.getSelectionModel().selectFirst();

        String[] temperlist={
                "null",
                "apostrophemask.py",
                "apostrophenullencode.py",
                "appendnullbyte.py",
                "base64encode.py",
                "between.py",
                "bluecoat.py",
                "chardoubleencode.py",
                "charencode.py",
                "charunicodeencode.py",
                "charunicodeescape.py",
                "commalesslimit.py",
                "commalessmid.py",
                "commentbeforeparentheses.py",
                "concat2concatws.py",
                "equaltolike.py",
                "escapequotes.py",
                "greatest.py",
                "halfversionedmorekeywords.py",
                "hex2char.py",
                "htmlencode.py",
                "ifnull2casewhenisnull.py",
                "ifnull2ifisnull.py",
                "informationschemacomment.py",
                "least.py",
                "lowercase.py",
                "luanginx.py",
                "modsecurityversioned.py",
                "modsecurityzeroversioned.py",
                "multiplespaces.py",
                "overlongutf8.py",
                "overlongutf8more.py",
                "percentage.py",
                "plus2concat.py",
                "plus2fnconcat.py",
                "randomcase.py",
                "randomcomments.py",
                "space2comment.py",
                "space2dash.py",
                "space2hash.py",
                "space2morecomment.py",
                "space2morehash.py",
                "space2mssqlblank.py",
                "space2mssqlhash.py",
                "space2mysqlblank.py",
                "space2mysqldash.py",
                "space2plus.py",
                "space2randomblank.py",
                "sp_password.py",
                "substring2leftright.py",
                "symboliclogical.py",
                "unionalltounion.py",
                "unmagicquotes.py",
                "uppercase.py",
                "varnish.py",
                "versionedkeywords.py",
                "versionedmorekeywords.py",
                "xforwardedfor.py"
        };
        ObservableList<String> list = FXCollections.observableArrayList();
        list.addAll(Arrays.asList(temperlist));
        t脚本.setItems(list);
        t脚本.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);  //多选模式
        t脚本.getSelectionModel().selectFirst();  //默认选择第一个null

    }

    @FXML
    void 开始执行(MouseEvent event) {
        OutputStreamWriter writer=null;
        try {
            if (!sqlcmd.exists()){
                sqlcmd.createNewFile();
            }
            writer = new OutputStreamWriter(new FileOutputStream(sqlcmd, false), "UTF-8");

            data = "python "+ Main.getSqlmapPath()+"/sqlmap.py --random-agent ";
            data+=tsqlcmd.getText().trim();

            if (Main.OSname.equals("Windows")){
                /*
                 *  作者：icefield
                 *  说明：windows系统防止命令执行完关闭系统
                 */
                data+="\n@pause";
            } else if(Main.OSname.equals("Linux")){

            }

            writer.write(data);
            writer.close();

            if (Main.OSname.equals("Windows")){
                Runtime.getRuntime().exec("cmd /c start " + System.getProperty("user.home") + "/sqlcmd.bat");
            } else if(Main.OSname.equals("Linux")){
                /*
                 *  作者：icefield
                 *  说明：linux环境适配，目前还有问题
                 */
                try {
                    Runtime.getRuntime().exec("chmod 777 " + System.getProperty("user.home") + "/sqlcmd.sh").waitFor();

                    Process process = Runtime.getRuntime().exec("bash " + System.getProperty("user.home") + "/sqlcmd.sh");
//                    LineNumberReader br = new LineNumberReader(new InputStreamReader(
//                            process.getInputStream()));
////                    StringBuffer sb = new StringBuffer();
//                    String line;
//                    while ((line = br.readLine()) != null) {
//                        System.out.println(line);
////                        sb.append(line).append("\n");
//                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(writer!=null){
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    @FXML
    void 开始构造(MouseEvent event) {
        String 参数 = 获取参数();
        tsqlcmd.setText(参数);
    }

    public  String 获取参数(){
        String paras="";
        String url = turl.getText().trim();
        paras+=" -u \""+url+"\"";
        if (!t脚本.getSelectionModel().getSelectedItem().equals("null")){
            ObservableList<String> items = t脚本.getSelectionModel().getSelectedItems();
            paras+=" --tamper \"";
            for (int i = 0; i < items.size(); i++) {
                paras+=items.get(i);
                if ((i < (items.size()) - 1)) {
                    paras += ",";
                }
            }
            paras+="\"";
        }
        if (cdb类型.isSelected()) {
            paras+=" --dbms="+tdb类型.getValue().toString();
        }
        if (c参数.isSelected()) {
            paras+=" -p \""+t参数.getText().trim()+"\"";
        }
        if (c前缀.isSelected()) {
            paras+=" --prefix=\""+t前缀.getText().trim()+"\"";
        }
        if (c后缀.isSelected()) {
            paras+=" --suffix=\""+t后缀.getText().trim()+"\"";
        }
        if (cos.isSelected()) {
            paras+=" --os=\""+tos.getText().trim()+"\"";
        }
        if (c跳参数.isSelected()) {
            paras+=" --skip=\""+t跳参数.getText().trim()+"\"";
        }
        if (c逻辑.isSelected()) {
            paras+=" --logic-negative";
        }

        if (c所有优化.isSelected()) {
            paras+=" -o";
        }
        if (c预测结果.isSelected()) {
            paras+=" --predict-output";
        }
        if (c持续连接.isSelected()) {
            paras+=" --keep-alive";
        }
        if (c只长度.isSelected()) {
            paras+=" --null-connection";
        }
        if (c线程.isSelected()) {
            paras+=" --threads=\""+t线程.getValue().toString()+"\"";
        }

        if (c字符串.isSelected()) {
            paras+=" --string=\""+t字符串.getText().trim()+"\"";
        }
        if (c正则.isSelected()) {
            paras+=" --regexp=\""+t正则.getText().trim()+"\"";
        }
        if (c代码.isSelected()) {
            paras+=" --code=\""+t代码.getText().trim()+"\"";
        }
        if (c等级.isSelected()) {
            paras+=" --level="+t等级.getValue().toString();
        }
        if (c风险.isSelected()) {
            paras+=" --risk=\""+t风险.getValue().toString()+"\"";
        }
        if (c技术.isSelected()) {
            paras+=" --technique="+t技术.getValue().toString()+"";
        }
        if (cu数.isSelected()) {
            paras+=" --union-cols=\""+tu数.getText().trim()+"\"";
        }

        if (cu字符.isSelected()) {
            paras+=" --union-char=\""+tu字符.getText().trim()+"\"";
        }
        if (c延迟.isSelected()) {
            paras+=" --time-sec=\""+t延迟.getText().trim()+"\"";
        }
        if (c指纹.isSelected()) {
            paras+=" --fingerprint";
        }
        if (c版本.isSelected()) {
            paras+=" --banner";
        }
        if (chex.isSelected()) {
            paras+=" --hex";
        }
        if (c无交互.isSelected()) {
            paras+=" --batch";
        }
        if (c详细度.isSelected()) {
            paras+=" -v "+t详细度.getValue().toString();
        }
        if (cpost.isSelected()) {
            paras+=" --data=\""+tpost.getText().trim()+"\"";
        }
        if (ccookie.isSelected()) {
            paras+=" --cookie=\""+tcookie.getText().trim()+"\"";
        }

        if (c当前用户.isSelected()) {
            paras+=" --current-user";
        }
        if (c当前库.isSelected()) {
            paras+=" --current-db";
        }
        if (c是否dba.isSelected()) {
            paras+=" --is-dba";
        }
        if (c所有用户.isSelected()) {
            paras+=" --users";
        }
        if (c密码.isSelected()) {
            paras+=" --passwords";
        }
        if (c权限.isSelected()) {
            paras+=" --privileges";
        }
        if (c角色.isSelected()) {
            paras+=" --roles";
        }
        if (c数据库.isSelected()) {
            paras+=" --dbs";
        }
        if (c表.isSelected()) {
            paras+=" --tables";
        }
        if (c字段.isSelected()) {
            paras+=" --columns";
        }
        if (c架构.isSelected()) {
            paras+=" --schema";
        }
        if (c计数.isSelected()) {
            paras+=" --count";
        }
        if (cdump.isSelected()) {
            paras+=" --dump";
        }
        if (c脱裤.isSelected()) {
            paras+=" --dump-all";
        }
        if (c搜索.isSelected()) {
            paras+=" --search";
        }
        if (c排除系统库.isSelected()) {
            paras+=" --exclude-sysdbs";
        }
        if (c第一字符.isSelected()) {
            paras+=" --first=\""+t第一字符.getText().trim()+"\"";
        }
        if (c第二字符.isSelected()) {
            paras+=" --last=\""+t第二字符.getText().trim()+"\"";
        }
        if (c始.isSelected()) {
            paras+=" --start=\""+t始.getText().trim()+"\"";
        }
        if (c末.isSelected()) {
            paras+=" --stop=\""+t末.getText().trim()+"\"";
        }
        if (c指定db.isSelected()) {
            paras+=" -D=\""+t指定db.getText().trim()+"\"";
        }
        if (c指定表.isSelected()) {
            paras+=" -T=\""+t指定表.getText().trim()+"\"";
        }
        if (c指定列.isSelected()) {
            paras+=" -C=\""+t指定列.getText().trim()+"\"";
        }
        if (csql.isSelected()) {
            paras+=" --sql-query=\""+tsql.getText().trim()+"\"";
        }

        if (c代理.isSelected()) {
            paras+=" --proxy==\""+t代理.getText().trim()+"\"";
        }
        if (c身份验证.isSelected()) {
            paras+=" --proxy-cred=\""+tname.getText().trim()+":"+t密码.getText().trim()+"\"";
        }
        if (c请求文件.isSelected()) {
            paras+=" -r \""+t请求文件.getText().trim()+"\"";
        }
        if (c读文件.isSelected()) {
            paras+=" --file-read \""+t读文件.getText().trim()+"\"";
        }
        if (c编辑文件.isSelected()) {
            paras+=" --file-write \""+t编辑文件.getText().trim()+"\"";
        }
        if (c写入文件.isSelected()) {
            paras+=" --file-dest \""+t写入文件.getText().trim()+"\"";
        }
        if (cShell.isSelected()) {
            paras+=" --os-shell";
        }

        return paras;
    }

    @FXML
    void 打开Post文件(MouseEvent event) {
        FileChooser fileChooser = new FileChooser();
        fileChooser.setTitle("请选择Post数据包");
        fileChooser.setInitialDirectory(new File(System.getProperty("user.home")));
        fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("TXT","*.txt"));
        File file = fileChooser.showOpenDialog(Main.stage);
        t请求文件.setText(file.getPath());
    }

}
